#include "jeu.h"

void jouer(SDL_Surface *ecran)
{
    /* ---- Initialisation du torrent de variables ---- */
    SDL_Surface *mario[4]={NULL}, *caisse[2]={NULL}, *mur=NULL, *objectif=NULL, *instructions=NULL, *fin=NULL;
    SDL_Rect pmur[200], pmario, pcaisse[100], pobjectif[100], pinstructions; // J'ai fait le choix de répertorier toutes les coordonnées
    SDL_Rect *ptrpmario=&pmario;
    SDL_Event event, eventFin;
    int continuer=1, passer=1, i=0, j=0, k=0, map[WTILES][HTILES]={{0}}, nMurs=0, nCaisses=0, nObjectifs=0, collision[4]={0}, level=1, suite=0, nNiveaux=0, source=1;
    int *ptrNiv=&level, *ptrnMurs=&nMurs, *ptrnCaisses=&nCaisses, *ptrnObj=&nObjectifs, *ptrSuite=&suite, *ptrnNiveaux=&nNiveaux;

    nombreNiveaux(ptrnNiveaux); // Donne le nombre de niveaux dans le fichier niveaux.lvl
    pinstructions.x=0;
    pinstructions.y=0;

    mario[0]=IMG_Load("GFX/mario_bas.gif");
    mario[1]=IMG_Load("GFX/mario_haut.gif");
    mario[2]=IMG_Load("GFX/mario_droite.gif");
    mario[3]=IMG_Load("GFX/mario_gauche.gif");
    caisse[0]=IMG_Load("GFX/caisse.png");
    caisse[1]=IMG_Load("GFX/caisse_ok.png");
    mur=IMG_Load("GFX/mur.png");
    objectif=IMG_Load("GFX/objectif.png");
    SDL_SetColorKey(objectif,SDL_SRCCOLORKEY,SDL_MapRGB(objectif->format,255,0,255));
    instructions=IMG_Load("GFX/jouer.png");
    fin=IMG_Load("GFX/fin.png");

    SDL_EnableKeyRepeat(100, 80);

    /* ---- Boucle affichant les instructions du jeu (mode d'emploi) ---- */
    while(passer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                passer=0;
                continuer=0;
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_SPACE:
                        passer=0;
                        break;
                    case SDLK_RETURN:
                        passer=0;
                        break;
                    case SDLK_ESCAPE:
                        passer=0;
                        continuer=0;
                        break;
                }
                break;
        }
        SDL_BlitSurface(instructions,NULL,ecran,&pinstructions);
        SDL_Flip(ecran);
    }

    SDL_FreeSurface(instructions);

    lireNiveau(map,*ptrNiv,nNiveaux,source); // On lit le premier niveau et on le charge dans map
    genererNiveau(map,ptrnMurs,ptrnCaisses,ptrnObj,pmur,ptrpmario,pcaisse,pobjectif); // On affecte les coordonnées aux objets

    while(continuer) // Boucle du jeu
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer=0;
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_UP:
                        if(collision[HAUT] != 1) // Si on peu monter
                        {
                            for(k=0;k<nCaisses;k++)
                            {   // Et si on a une caisse dans la direction où on va
                                if(pmario.y == pcaisse[k].y+TILE_SIZE && pmario.x == pcaisse[k].x && pcaisse[k].y != 0)
                                {
                                    pcaisse[k].y = pcaisse[k].y - TILE_SIZE; // On emmène la caisse et...
                                }
                            }
                            pmario.y = pmario.y - TILE_SIZE; // ...on y va !
                        }
                        j=HAUT; // Mario sera dirigé vers le haut
                        break;
                    case SDLK_DOWN:
                        if(collision[BAS] != 1)
                        {
                            for(k=0;k<nCaisses;k++)
                            {
                                if(pmario.y == pcaisse[k].y-TILE_SIZE && pmario.x == pcaisse[k].x && pcaisse[k].y != 374)
                                {
                                    pcaisse[k].y = pcaisse[k].y + TILE_SIZE;
                                }
                            }
                            pmario.y = pmario.y + TILE_SIZE;
                        }
                        j=BAS;
                        break;
                    case SDLK_RIGHT:
                        if(collision[DROITE] != 1)
                        {
                            for(k=0;k<nCaisses;k++)
                            {
                                if(pmario.x == pcaisse[k].x-TILE_SIZE && pmario.y == pcaisse[k].y && pcaisse[k].x != 374)
                                {
                                    pcaisse[k].x = pcaisse[k].x + TILE_SIZE;
                                }
                            }
                            pmario.x = pmario.x + TILE_SIZE;
                        }
                        j=DROITE;
                        break;
                    case SDLK_LEFT:
                        if(collision[GAUCHE] != 1)
                        {
                            for(k=0;k<nCaisses;k++)
                            {
                                if(pmario.x == pcaisse[k].x+TILE_SIZE && pmario.y == pcaisse[k].y && pcaisse[k].x != 0)
                                {
                                    pcaisse[k].x = pcaisse[k].x - TILE_SIZE;
                                }
                            }
                            pmario.x = pmario.x - TILE_SIZE;
                        }
                        j=GAUCHE;
                        break;
                    case SDLK_r: // On recommence le niveau
                        lireNiveau(map,*ptrNiv,nNiveaux,1);
                        genererNiveau(map,ptrnMurs,ptrnCaisses,ptrnObj,pmur,ptrpmario,pcaisse,pobjectif);
                        j=BAS;
                        break;
                    case SDLK_l:
                        source=2;
                        lireNiveau(map,1,1,source); //Il n'est possible que de créer un seul niveau dans custom.lvl
                        genererNiveau(map,ptrnMurs,ptrnCaisses,ptrnObj,pmur,ptrpmario,pcaisse,pobjectif);
                        j=BAS;
                        break;
                    case SDLK_ESCAPE:
                        continuer=0;
                    case SDLK_s:
                        sauvegarder(level);
                        break;
                    case SDLK_c:
                        charger(ptrNiv);
                        lireNiveau(map,*ptrNiv,nNiveaux,1);
                        genererNiveau(map,ptrnMurs,ptrnCaisses,ptrnObj,pmur,ptrpmario,pcaisse,pobjectif);
                        j=BAS;
                        break;
                        break;
                }
                break;
        }
        if(suite==1) // Si on a fini un niveau :
        {
            lireNiveau(map,*ptrNiv,nNiveaux,1); // On passe au suivant
            genererNiveau(map,ptrnMurs,ptrnCaisses,ptrnObj,pmur,ptrpmario,pcaisse,pobjectif);
            j=BAS; // Mario étant toujours dirigé vers le bas au début de chaque niveau
            suite=0;
        }
        collisionChecker(pmur, pcaisse, pmario, nMurs, nCaisses, collision); // On vérifie les directions possibles pour avancer
        SDL_FillRect(ecran,NULL,SDL_MapRGB(ecran->format,255,255,255));
        for(i=0;i<nMurs;i++)
        {
            SDL_BlitSurface(mur,NULL,ecran,&pmur[i]); // On blit tous les murs
        }
        for(i=0;i<nObjectifs;i++)
        {
            SDL_BlitSurface(objectif,NULL,ecran,&pobjectif[i]); // Tous les objectifs
        }
        // Combien de caisses sont validées et lesquelles sont elles ?
        caisseValidee(nObjectifs, nCaisses, ptrNiv, ptrSuite, &source, pcaisse, pobjectif, caisse, ecran);
        SDL_BlitSurface(mario[j],NULL,ecran,&pmario);
        SDL_Flip(ecran);
        /* --- Condition pour montrer la fin du jeu --- */
        if(level == nNiveaux+1)
        {
            passer=1;
            while(passer)
            {
                SDL_WaitEvent(&eventFin);
                switch(eventFin.type)
                {
                    case SDL_QUIT:
                        passer=0;
                        continuer=0;
                        break;
                    case SDL_KEYDOWN:
                        switch(eventFin.key.keysym.sym)
                        {
                            case SDLK_SPACE:
                                continuer=0;
                                passer=0;
                                break;
                            case SDLK_RETURN:
                                continuer=0;
                                passer=0;
                                break;
                            case SDLK_ESCAPE:
                                continuer=0;
                                passer=0;
                                break;
                        }
                        break;
                }
                SDL_BlitSurface(fin,NULL,ecran,&pinstructions);
                SDL_Flip(ecran);
            }
            SDL_FreeSurface(fin);
        }
    /* --- Fin de la condition sur la fin du jeu --- */
    }

    for(i=0;i<4;i++)
    {
        SDL_FreeSurface(mario[i]);
    }
    SDL_FreeSurface(caisse[0]);
    SDL_FreeSurface(caisse[1]);
    SDL_FreeSurface(mur);
    SDL_FreeSurface(objectif);
}
